import os
import uuid

from django.contrib.auth import login, authenticate, logout

# Create your views here.
from django_redis import get_redis_connection
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet

from apps.users.models import User
from apps.users.serializers import UserModelSerializer
from common.exception_handler import BusinessException
from common.my_pagiantion import MyPageNumber
from common.redis_constants import IMG_CODE_PREFIX
from common.result import success, fail
from config.settings import PROJECT_CACHE_NAME

AVATAR_PREFIX = "avatar_"


def verify_param(request):
    username = request.data.get("username")
    password = request.data.get("password")
    img_code_id = request.data.get("img_code_id")
    img_code = request.data.get("img_code")
    if not username or not password or not img_code_id or not img_code:
        raise BusinessException("缺失参数")
    key = IMG_CODE_PREFIX + img_code_id
    conn = get_redis_connection(PROJECT_CACHE_NAME)
    img_code_in_redis = conn.get(key)
    if not img_code_in_redis:
        raise BusinessException("验证码已过期！")
    img_code_in_redis = img_code_in_redis.decode().lower()
    if img_code_in_redis != img_code.lower():
        raise BusinessException("验证码错误！")
    # 删除图片验证码
    conn.delete(key)
    return username, password


class UserModelViewSet(ModelViewSet):
    def get_queryset(self):
        return User.objects.filter(is_deleted=False)

    def get_serializer_class(self):
        return UserModelSerializer

    pagination_class = MyPageNumber

    def update(self, request, *args, **kwargs):
        instance = self.get_object()
        username = request.data.get("username")
        signature = request.data.get("signature")
        introduction = request.data.get("introduction")
        data = {}
        if username:
            data["username"] = username
        if signature:
            data["signature"] = signature
        if introduction:
            data["introduction"] = introduction
        serializer = self.get_serializer(instance, data=data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return success("信息更新成功！", serializer.data)

    def retrieve(self, request, *args, **kwargs):
        return success(None, super().retrieve(request, *args, **kwargs).data)

    def destroy(self, request, *args, **kwargs):

        return success("删除成功", super().destroy(request, *args, **kwargs).data)

    @action(methods=["post"], detail=False, url_path="register")
    def register(self, request):
        """
        注册新用户
        """
        username, password = verify_param(request)
        serializer = self.get_serializer(data={"username": username, "password": password})
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return success("注册成功！", serializer.data)

    @action(methods=["post"], detail=False, url_path="login")
    def login(self, request):
        """
        用户登录
        """
        username, password = verify_param(request)
        user = authenticate(username=username, password=password)
        if not user:
            return fail("用户名或密码错误！")
        # 登陆状态保持，默认两周
        login(request, user=user)
        # redis里面也存储一份， 也是两周
        request.session.set_expiry(60 * 60 * 24 * 14)
        return success("登陆成功！", UserModelSerializer(user).data)

    @action(methods=["post"], detail=False, url_path="logout")
    def logout(self, request):
        """
        用户登出
        """
        # 登陆状态保持，默认两周
        logout(request)
        response = Response("登出成功！")
        response.cookies.clear()
        return response

    @action(methods=["post"], detail=False, url_path="update_avatar")
    def update_avatar(self, request):
        user = request.user
        if not request.user.id:
            return fail("请先登录！")  # 等静态页面完成之后可以重定向到登陆页面
        avatar = request.data.get("avatar")
        old_avatar = request.data.get("old_avatar")
        avatar_path = os.path.dirname(os.path.dirname(
            os.path.dirname(os.path.abspath(__file__)))).replace("\\", "/") + old_avatar
        # 如果旧头像存在就删除
        if os.path.exists(avatar_path) and not avatar_path.__contains__("default"):
            os.remove(avatar_path)
        if avatar.content_type == "image/jpeg" or avatar.content_type == "image/png":
            file_type = avatar.content_type.split("/")[1]
            user.avatar.save(AVATAR_PREFIX + uuid.uuid4().__str__() + "." + file_type, avatar)
            return success("上传成功！", {"url": user.avatar.name})
        else:
            return fail("头像格式错误！请上传：jpeg/png")
